<script>
    let activeEffect = null;
    class Dep {
        constructor(value) {
            this._value = value;
            this.effects = new Set(); //使用Set对象存放所有effect
        }
        get value() {
            this.track()
            return this._value;
        }
        set value(newValue) {
            if (newValue != this._value) {
                this._value = newValue;
            }
            this.trigger()
        }

        track() {
            if (activeEffect) {
                this.effects.add(activeEffect);
            }
        }
        trigger() {
            this.effects.forEach(effect => {
                effect()
            })
        }
    }

    function watchEffect(effect) {
        activeEffect = effect;
        effect();
        activeEffect = null;
    }
    const targetMap = new WeakMap(); //创建全局Map存储被监测对象的所有属性的dep

    function findDep(target, key) {
        let depsMap = targetMap.get(target);
        if (!depsMap) {
            depsMap = new Map(); // depsMap存储属性的dep
            targetMap.set(target, depsMap);
        }

        let dep = depsMap.get(key);
        if (!dep) {
            dep = new Dep();
            depsMap.set(key, dep); //建立被监测对象属性key和dep的关系
        }
        return dep;
    }
    const reactiveHandlers = {
        get(target, key, receiver) {
            const dep = findDep(target, key)
            dep.track();
            return Reflect.get(target, key, receiver);
        },
        set(target, key, value, receiver) {
            const dep = findDep(target, key)
            const res = Reflect.set(target, key, value, receiver);
            dep.trigger();
            return res;
        }
    }

    function reactive(raw) {
        // es5 的defineProperty实现
        /* Object.keys(raw).forEach(key => {
            let dep = new Dep();
            let value = raw[key];
            Object.defineProperty(raw, key, {
                get() {
                    dep.track();
                    return value;
                },
                set(newValue) {
                    value = newValue;
                    dep.trigger();
                }
            })
        })
        return raw; */
        return new Proxy(raw, reactiveHandlers)
    }
    // targetMap
    /* {
        count: 0,
        name: ['zs', 'ls']
    } */
    // depsMap 存放的 count和 name
    const state = reactive({
        count: 0,
        name: ['zs', 'ls']
    })
    watchEffect(() => {
        console.log(state.count);
        console.log(state.name);
    })
    state.count++;
    state.name = ['ww'];
</script>